﻿#include "MyVtkInteractorSelect.h"

MyVtkInteractorSelect* MyVtkInteractorSelect::New()
{
    return new MyVtkInteractorSelect();
}

MyVtkInteractorSelect::MyVtkInteractorSelect()
{
    m_SelectionManager = std::make_shared<SelectionManager>();
    m_HoverManager = std::make_shared<SelectionManager>();
    m_ActorManager = GetActorManagerInstance();
    m_MultiPickMode = true;
    m_CurrentPickMode = PickMode::VOLUME;

    m_SelectionManager->SetHighlightColor(255, 255, 0);
    m_HoverManager->SetHighlightColor(255, 0, 255);

    // 创建拾取器
    m_CellPicker = vtkSmartPointer<vtkCellPicker>::New();
    m_CellPicker->SetTolerance(0.001);
}

MyVtkInteractorSelect::~MyVtkInteractorSelect()
{
}

void MyVtkInteractorSelect::OnLeftButtonDown()
{


    // Ctrl+左键进行拾取
    Pick();
    // 通知外部选择已更改
    if(this->SelectionChangedCallback)
    {
        this->SelectionChangedCallback();
    }

    // 普通左键行为
    vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
}

void MyVtkInteractorSelect::OnMouseMove()
{

    Hover();

    // 普通左键行为
    vtkInteractorStyleTrackballCamera::OnMouseMove();
}

void MyVtkInteractorSelect::SetMultiPickMode(bool enable)
{
    m_MultiPickMode = enable;
}

bool MyVtkInteractorSelect::GetMultiPickMode()
{
    return m_MultiPickMode;
}

void MyVtkInteractorSelect::SetPickMode(PickMode mode)
{
    m_CurrentPickMode = mode;
}

std::shared_ptr<SelectionManager> MyVtkInteractorSelect::GetSelectionManagerManager() const
{
    return m_SelectionManager;
}

void MyVtkInteractorSelect::Pick()
{
    if(!this->CurrentRenderer || !this->Interactor)
    {
        return;
    }

    auto curRenderWin = this->CurrentRenderer->GetRenderWindow();
    if(!curRenderWin)
    {
        return;
    }

    int x = this->Interactor->GetEventPosition()[0];
    int y = this->Interactor->GetEventPosition()[1];

    m_CellPicker->Pick(x, y, 0, this->CurrentRenderer);
    vtkActor* pickedActor = m_CellPicker->GetActor();

    /* if(!pickedActor)
     {
         m_HoverManager->ClearAllSelectedActors();
         return;
     }*/

    if(pickedActor)
    {
        //检查是否Hover
        bool bHasHover = m_HoverManager->IsActorHighlighted(pickedActor);
        if(bHasHover)
        {
            m_HoverManager->ClearAllSelectedActors();
        }

        // 检查是否选中
        bool bHasSelected = m_SelectionManager->IsActorHighlighted(pickedActor);
        if(m_MultiPickMode)
        {
            if(bHasSelected)
            {
                // 在多选模式下取消已经选中对象
                m_SelectionManager->RemoveSeletedActor(pickedActor);
            }
            else
            {
                // 添加选中
                PickMode mode = m_ActorManager->GetActorMode(pickedActor);
                m_SelectionManager->AddSelectedActor(pickedActor, mode);
            }
        }
        else
        {
            m_SelectionManager->ClearAllSelectedActors();

            // 添加选中
            PickMode mode = m_ActorManager->GetActorMode(pickedActor);
            m_SelectionManager->AddSelectedActor(pickedActor, mode);
        }

        curRenderWin->Render();
        return;
    }
}

void MyVtkInteractorSelect::Hover()
{
    if(!this->CurrentRenderer || !this->Interactor)
    {
        return;
    }

    auto curRenderWin = this->CurrentRenderer->GetRenderWindow();
    if(!curRenderWin)
    {
        return;
    }

    int x = this->Interactor->GetEventPosition()[0];
    int y = this->Interactor->GetEventPosition()[1];

    m_CellPicker->Pick(x, y, 0, this->CurrentRenderer);
    vtkActor* pickedActor = m_CellPicker->GetActor();

    if(!pickedActor)
    {
        m_HoverManager->ClearAllSelectedActors();
        curRenderWin->Render();
        return;
    }

    if(pickedActor)
    {
        // 检查是否已经选中
        bool bHasSelected = m_SelectionManager->IsActorHighlighted(pickedActor);
        if(bHasSelected)
        {
            return;
        }

        //清楚现有高亮
        m_HoverManager->ClearAllSelectedActors();

        // 添加高亮
        PickMode mode = m_ActorManager->GetActorMode(pickedActor);
        m_HoverManager->AddSelectedActor(pickedActor, mode);

        curRenderWin->Render();
        return;
    }


}

void MyVtkInteractorSelect::SetSelectionChangedCallback(std::function<void()> callback)
{
    SelectionChangedCallback = callback;
}

void MyVtkInteractorSelect::SelectActor(vtkActor* actor, bool addToSelection)
{
    if(!actor) return;

    if(!addToSelection || !m_MultiPickMode)
    {
        m_SelectionManager->ClearAllSelectedActors();
    }

    if(m_SelectionManager->IsActorHighlighted(actor))
    {
        m_SelectionManager->RemoveSeletedActor(actor);
    }
    else
    {
        PickMode mode = m_ActorManager->GetActorInfo(actor).mode;
        m_SelectionManager->AddSelectedActor(actor, mode);
    }

    if(this->Interactor && this->Interactor->GetRenderWindow())
    {
        this->Interactor->GetRenderWindow()->Render();
    }
}